<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
    <style src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></style>
    <title>Document</title>
    <style>

        .node {
            cursor: pointer;
        }

        .node circle {
            fill: #fff;
            stroke: steelblue;
            stroke-width: 1.5px;
        }

        .node text {
            font: 10px sans-serif;
        }

        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 1.5px;
        }

        .link2 {
            fill: none;
            stroke: #f00;
            stroke-width: 1.5px;
        }

    </style>
</head>
<body>
</body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/jquery-3.2.1.min.js" charset="utf-8"></script>
<script>
    //<![CDATA[
    $.post("/zp/get2D/1",null,function (root) {
        var margin = {top: 20, right: 120, bottom: 20, left: 120},
            width = 1024 - margin.right - margin.left,
            height = 798 - margin.top - margin.bottom;
        var i = 0,
            duration = 750,
            tree = d3.layout.tree().nodeSize([90, 60]);

        var diagonal = d3.svg.diagonal()
            .projection(function(d) { return [d.x, d.y]; });

        //Redraw for zoom
        function redraw() {
            //console.log("here", d3.event.translate, d3.event.scale);
            svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
        }

        var svg = d3.select("body").append("svg").attr("width", 1500).attr("height", 700)
            .call(zm = d3.behavior.zoom().scaleExtent([1,3]).on("zoom", redraw)).append("g")
            .attr("transform", "translate(" + 512 + "," + 50 + ")");

        //necessary so that zoom knows where to zoom and unzoom from
        zm.translate([512, 50]);

        //d3.json("flare.json", function(error, flare)
        //  if (error) throw error;

        root.x0 = 0;
        root.y0 = height / 2;

        function collapse(d) {
            if (d.hasChild=="yes"&&d.isLoad=="yes") {
                d._children = d.children;
                d._children.forEach(collapse);
                d.children = null;
            }
            if (d.hasChild=="yes"&&d.isLoad=="no") {
                d._children =[];
                d.children = [];
            }
        }

        root.children.forEach(collapse);
        update(root);


        d3.select(self.frameElement).style("height", "800px");

        function update(source) {

            // Compute the new tree layout.
            var nodes = tree.nodes(root).reverse(),
                links = tree.links(nodes);

            // Normalize for fixed-depth.
            nodes.forEach(function(d) { d.y = d.depth * 180; });

            // Update the nodes…
            var node = svg.selectAll("g.node")
                .data(nodes, function(d) { return d.id || (d.id = ++i); });

            // Enter any new nodes at the parent's previous position.
            var nodeEnter = node.enter().append("g")
                .attr("class", "node")
                .attr("transform", function(d) { return "translate(" + source.x0 + "," + source.y0 + ")"; })
                .on("click", click);

            nodeEnter.append("circle")
                .attr("r", 1e-6)
                .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

            nodeEnter.append("text")
                .attr("x", function(d) { return d.children || d._children ? 13 : -10; })
                .attr("cy", ".35em")
                .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
                .text(function(d) { return d.name; })
                .style("fill-opacity", 1e-6);

            // Transition nodes to their new position.
            var nodeUpdate = node.transition()
                .duration(duration)
                .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

            nodeUpdate.select("circle")
                .attr("r", 20)
                .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

            nodeUpdate.select("text")
                .style("fill-opacity", 1);

            // Transition exiting nodes to the parent's new position.
            var nodeExit = node.exit().transition()
                .duration(duration)
                .attr("transform", function(d) { return "translate(" + source.x + "," + source.y + ")"; })
                .remove();

            nodeExit.select("circle")
                .attr("r", 1e-6);

            nodeExit.select("text")
                .style("fill-opacity", 1e-6);

            // Update the links…
            var link = svg.selectAll("path.link")
                .data(links, function(d) { return d.target.id; });

            // Enter any new links at the parent's previous position.
            link.enter().insert("path", "g")
                .attr("class", "link")
                .attr("d", function(d) {
                    var o = {x: source.x0, y: source.y0};
                    return diagonal({source: o, target: o});
                });
            link.transition()
                .duration(duration)
                .attr("d", diagonal);

            // Transition exiting nodes to the parent's new position.
            link.exit().transition()
                .duration(duration)
                .attr("d", function(d) {
                    var o = {x: source.x, y: source.y};
                    return diagonal({source: o, target: o});
                })
                .remove();

            // Stash the old positions for transition.
            nodes.forEach(function(d) {
                d.x0 = d.x;
                d.y0 = d.y;
            });
        }

        function getNode(id){
            var mynodes = null;
            $.ajax({
                url : "/zp/get2D/"+id,
                async : false, // 注意此处需要同步
                type : "get",
                dataType : "json",
                success : function(data) {
                    mynodes = data;
                }
            });
            return mynodes;
        }

        // Toggle children on click.
        function click(d) {
            if(d.hasChild=="yes"&&d.isLoad=="no")
            {
                var mnodes = getNode(d.id);
                for(n in mnodes.children)
                {
                    if(mnodes.children[n].hasChild=="yes")
                    {
                        mnodes.children[n].children=[]
                        mnodes.children[n]._children=[]
                    }
                }
                d.isLoad="yes"
                d.children = mnodes.children;
                d._children = null;
                update(d);
                return;
            }
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else if(d._children){
                d.children = d._children;
                d._children = null;
            }
            update(d);
        }
        
    })
    //]]>
</script>
</html>
